/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package elaborate.tag_analysis.client.graph;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 *
 * @author lendle
 */
public class SimpleSparseGraph implements Graph, Cloneable{
    private List<Object> points=new ArrayList();
    private Map<Object, ConnectionListEntry> connectionMap=new HashMap<Object, ConnectionListEntry>();
    private boolean directed=false;
    
    private Map<Object, Map<Object, String>> connectionMaps=new HashMap<Object, Map<Object, String>>();
    private Map<Object, String> _connectionMap=new HashMap<Object, String>();
    private static final String delim="~!@#$%^&*()";//delim between src and target
//    private Object cachedConnectionSrc=null;
//    private Map<Object, String> cachedConnectionTarget=new HashMap<Object, String>();
    
    @Override
    public List<Object> getPoints() {
        return new ArrayList(points);
    }

    public void setConnected(Object src, Object target){
        this._setConnected(src, target);
        if(!this.directed){
            this._setConnected(target, src);
        }
    }
    
    private void _setConnected(Object src, Object target){
        //no need to change status
        if(this.isConnected(src, target)){
            return;
        }
        
        //////////////////////////
        
        //ConnectionListEntry entry=getConnectionListEntry(src);
        this.getConnectionMap(src).put(target, "");
         
    }
    
    @Override
    public boolean isConnected(Object src, Object target) {
        return this.getConnectionMap(src).get(target)!=null;
        //return this._connectionMap.get(src+delim+target)!=null;
//        ConnectionListEntry entry=getConnectionListEntry(src);
//        return entry.getConnectedTargetList().containsKey(target);
    }
    
    private Map<Object, String> getConnectionMap(Object src){
        Map<Object, String> map=this.connectionMaps.get(src);
        if(map==null){
            map=new HashMap<Object, String>();
            this.connectionMaps.put(src, map);
        }
        return map;
    }
    
    private ConnectionListEntry getConnectionListEntry(Object src){
        ConnectionListEntry entry=this.connectionMap.get(src);
        if(entry==null){
            entry=new ConnectionListEntry();
            this.connectionMap.put(src, entry);
        }
        return entry;
    }

    @Override
    public boolean isDirected() {
        return false;
    }
    
    public void setDirected(boolean directed){
        this.directed=directed;
    }

    @Override
    public void addPoint(Object point) {
        this.points.add(point);
    }
    
    class ConnectionListEntry{
        private Map<Object, String> connectedTargetList=new HashMap<Object, String>();

        public Map<Object, String> getConnectedTargetList() {
            return connectedTargetList;
        }
    }

    @Override
    public Graph clone() throws CloneNotSupportedException {
        SimpleSparseGraph cloned=(SimpleSparseGraph) super.clone();
        cloned.connectionMap=new HashMap<Object, ConnectionListEntry>();
        cloned.connectionMap.putAll(connectionMap);
        cloned.points=new ArrayList<Object>();
        cloned.points.addAll(this.points);
        cloned.directed=this.directed;
        return cloned;
    }
    
    
}
